You are on page 1of 69

Buat Komponen Delphi

Anda Sendiri!
Membuat komponen Delphi secara mudah dan
cepat dengan pengenalan Object Oriented
Programming
Daftar Isi
Daftar Isi ............................................................................................................................. i
Sekapur Sirih...................................................................................................................... 1
1 Mengapa Membuat Komponen Sendiri? .................................................................. 2
1.1 Apa itu komponen?.......................................................................................................2
1.2 Mengapa Kita Membuat Komponen?.........................................................................3
1.3 Apa saja yang perlu diketahui untuk membuat komponen? ....................................5
2 Object Oriented Programming (OOP) ...................................................................... 7
2.1 Apa itu OOP? ................................................................................................................7
2.2 Apa perbedaan OOP dengan Procedural Programming ..........................................8
3 Konsep-konsep Dasar OOP ..................................................................................... 10
3.1 Kelas .............................................................................................................................10
3.2 Enkapsulasi..................................................................................................................11
3.3 Pewarisan.....................................................................................................................12
3.4 Polimorfisme................................................................................................................13
4 Disain dan Implementasi Pemrograman Berorientasi Object dengan Delphi...... 14
4.1 Bermula dari Masalah, Diakhiri dengan Solusi Program.......................................14
4.1.1 Fase Analisis..........................................................................................................................14
4.1.2 Fase Disain ............................................................................................................................14
4.1.3 Fase Implementasi .................................................................................................................15
4.2 Studi Kasus – Menganalisis, Mendisain, dan Mengimplementasikan Kelas.........16
4.2.1 Analisis ..................................................................................................................................16
4.2.2 Disain.....................................................................................................................................17
4.2.3 Implementasi .........................................................................................................................20
5 Membuat Komponen Sederhana ............................................................................. 33
5.1 Langkah-langkah Membuat Komponen...................................................................34
5.1.1 Menentukan Superclass dari Komponen ...............................................................................34
5.1.2 Membuat Komponen Sederhana Langkah demi Langkah .....................................................35
6 Contoh Komponen-Komponen ................................................................................ 48
6.1 Komponen yang Terhubung ke Basisdata ................................................................48
6.1.1 TWWDBNavigator................................................................................................................48
6.1.2 TWWDBDateTimePicker...................................................... Error! Bookmark not defined.
7 Referensi................................................................................................................... 67

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman i
Sekapur Sirih
Saya tertarik untuk membuat buku tentang cara membuat komponen dengan Delphi
karena kurangnya buku dalam bahasa Indonesia yang membahas pemrograman
berorientasi objek dengan Delphi yang dilengkapi pembuatan komponen. Buku ini
ditujukan bagi mereka yang sudah mengenal Delphi secara singkat dan ingin mengenal
bagaimana membuat komponen dengan Delphi. Diasumsikan pembaca sudah mengenal
bahasa Pascal atau operator, pembuatan fungsi dan prosedur di Delphi.
Komponen di Delphi sangat powerful, bahkan dapat dikatakan kekuatan utama
pemrograman dalam Delphi adalah pada pemanfaatan komponen, reusability yang sangat
tinggi, dan sangat mendukung dalam RAD (Rapid Application Development). Anda akan
menemukan bahwa dalam dunia nyata, delivery project tepat pada waktunya sangat
ditentukan oleh lamanya pengembangan aplikasi. Ketersediaan komponen dalam
framework yang dapat digunakan berulang kali akan memperpendek waktu
pengembangan aplikasi. Dengan kata lain, memanfaatkan secara maksimal komponen di
Delphi, akan membuat anda benar-benar produktif. Kata kuncinya adalah reusability.
Delphi yang saya gunakan dalam buku ini adalah versi 6. Meskipun demikian,
konsep pembuatan komponennya dapat digunakan pada versi berikutnya. Ilmu saya
dalam menggunakan Borland Delphi masih sangat dangkal. Semakin saya mencoba
menyelami, semakin terasa bahwa ilmu yang saya pelajari masih sangat sedikit. Hal ini
disebabkan karena selama ini hanya mengerjakan proyek secara komersial dengan
menggunakan framework yang tidak terlalu jauh berubah. Selama ini hanya berkisar pada
aplikasi client server yang terkoneksi ke database. Kesibukan dalam dunia pekerjaan
terkadang melenakan kita untuk mempelajari sisi yang lebih dalam dari suatu bahasa
pemrograman. Buku ini ditulis lebih dari tiga tahun lamanya.
Komponen yang ada dalam buku ini ditulis oleh pemula untuk pemula. Jika anda
adalah programer Delphi yang sangat berpengalaman, terutama dalam pembuatan
komponen, anda mungkin akan menemui bahwa komponen yang ditulis dalam buku ini
masih sangat mungkin untuk dioptimalkan dari segi algoritma maupun efisiensi kerja
program. Kritik dan saran Anda saya nantikan, di wishknew@yahoo.com atau di blog
http://wishknew.modblog.com .

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 1
1 Mengapa Membuat Komponen Sendiri?
1.1 Apa itu komponen?

K
omponen pada dasarnya adalah objek-objek yang dapat dimanipulasi pada
saat kita merancang suatu program. Komponen Delphi terdiri dari objek-
objek dalam bentuk kode Pascal yang biasanya mempunyai atribut dan
fungsi yang dapat menggambarkan tingkah laku dari komponen tersebut.
Komponen tersebut biasanya diletakkan pada palet komponen dan bisa dimanipulasi di
atas form designer.

Contoh beberapa komponen di atas form designer


Komponen dapat terbentuk dari beberapa komponen lain yang memiliki sifat
berbeda-beda dan membentuk suatu sifat gabungan baru yang berbeda dari komponen-
komponen pembangunnya. Sebagai ilustrasi kita bisa mengibaratkan objek “rumah” yang
dapat terbentuk dari komponen “pintu”, “jendela”, “genting”, “lantai”, dan sebagainya.
Komponen “pintu” terdiri dari elemen “kaca”, “kayu”, komponen “pegangan pintu”, dan
seterusnya. Seluruh komponen yang bersatu tersebut pada akhirnya membentuk suatu
entitas baru yang kita sebut “rumah”.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 2
1.2 Mengapa Kita Membuat Komponen?
Membangun rumah dari nol tanpa ada komponen “pintu”, “jendela”, dan
“genting” akan lebih lama daripada jika kesemua komponen itu telah tersedia dan siap
untuk kita “manipulasi” sehingga menjadi rumah yang kita inginkan. Tanpa komponen,
kita akan membutuhkan waktu yang lama untuk membuat suatu program. Komponen
biasanya dibuat karena beberapa alasan. Alasan yang paling penting adalah kita tidak
perlu atau tidak mungkin mengetahui (atau bahkan tidak mau tahu) detail semua hal
ketika kita akan memprogram. Seperti ketika mengendarai mobil, kita tidak perlu tahu
detail bagaimana mesin suatu mobil bekerja. Bagaimana piston bekerja, bahan bakar
dicampur, dan seterusnya. Kita hanya perlu tahu bagaimana kita menjalankan mobil itu,
atau dengan kata lain kita cukup mengenal behaviour atau perilaku mobil yang akan kita
kendarai.
Hampir seluruh mobil dijalankan dengan memasukkan kunci dan memutarnya ke
ke kanan. Ini adalah salah satu bentuk antarmuka (interface) antara pengendara dengan
mobil. Bagi perusahaan produsen mobil, mereka tidak perlu membuat seluruh komponen
yang dipakai. Ada perusahaan lain yang khusus membuat ban, knalpot, radiator, kursi,
dan seterusnya. Produsen mobil (assembler) tahu bagaimana masing-masing komponen
itu bekerja dan berinteraksi dengan komponen lainnya. Pada akhirnya seluruh komponen
yang disatukan itu menjadi sebuah komponen atau objek baru, yang dinamakan “mobil”,
dengan behaviour yang unik dan berbeda dari komponen-komponen penyusunnya.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 3
Mengapa kita harus membuat komponen yang rumit kalau kita bisa membuat
program dengan memanipulasi komponen yang sudah ada atau membuat kode
program yang bisa melakukan apa yang kita inginkan?
− Membuat komponen menjadi penting (dan akan sangat menguntungkan
secara ekonomi) bila kita ingin membuat sebuah komponen baru yang akan
dipergunakan berkali-kali dalam setiap project yang akan kita buat
− Membuat komponen membuat aplikasi kita menjadi lebih handal, dengan
memisahkan elemen-elemen program kita dengan pendekatan logika kelas
berorientasi objek
Pertanyaan selanjutnya adalah darimana kita mendapatkan komponen?
Jawabannya adalah build or buy, buat komponen sendiri atau beli. Kita membuat
komponen sendiri karena beberapa atau salah satu dari hal berikut :
− Kita tidak mendapatkan penjual komponen itu atau karena memang belum ada
yang pernah membuatnya
− Membuat komponen sendiri (sering) lebih murah daripada membelinya
(prinsip ekonomi)
− Membuat komponen sendiri lebih memberikan kepuasan batin (intangible
value) kepada seorang programmer
− Kita ingin berbagi kepada programmer lain, dengan harapan programmer lain
bisa menggunakan komponen yang sudah kita buat, baik dibagikan secara
gratis ataupun dengan lisensi berbayar
Kita menggunakan komponen yang sudah ada ketika :
− Kita belum bisa membuatnya (mungkin karena belum membaca buku ini ☺)
− Waktu yang tersisa untuk delivery project tidak memungkinkan kita untuk
membuatnya sendiri
− Prinsip “Don’t reinvent the wheel”. Kalau harganya terjangkau atau bahkan
free, mengapa kita membuatnya kalau bisa memakai yang sudah dibuat orang
lain?

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 4
1.3 Apa saja yang perlu diketahui untuk membuat komponen?
Untuk membuat komponen Delphi, pertama-tama kita harus mengenal bagaimana
memprogram dengan Delphi. Semua sintaks-sintaks, operator, kata kunci, dan seterusnya
harus kita pahami. Buku ini tidak dimaksudkan untuk belajar Delphi dari awal. Jika anda
belum terlalu familiar dengan sintaks Pascal / Delphi, saya anjurkan anda untuk membaca
buku-buku yang berisi tentang Pemrograman Pascal / Delphi tingkat awal.
Berikutnya yang kedua adalah mengenal komponen yang ada pada Delphi. Ada dua jenis
komponen yang ada pada Delphi, yaitu komponen nonvisual dan komponen visual.
Komponen nonvisual tidak terlihat pada saat program dijalankan, namun dapat dirasakan
efeknya. Komponen-komponen ini menyembunyikan suatu atribut tertentu dan
memungkinkan programmer untuk mengubah beberapa karakteristiknya melalui Object
Inspector pada saat design time dan running time. Contoh komponen nonvisual adalah
TDatasource, TTimer, dan TTable. Berbeda dengan komponen nonvisual, komponen
visual dapat dilihat oleh end user ketika program berjalan. Komponen-komponen ini
diturunkan dari TControl, sebuah kelas yang memiliki atribut dan fungsi yang berkaitan
dengan visualisasi seperti Top, Left, Color, dan seterusnya. Contohnya adalah TMemo,
TLabel, TEditBox, dan sebagainya. Beberapa kelas dasar yang sangat penting untuk

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 5
diketahui adalah TObject, Exception, TPersistent, TComponent, TControl, dan
TWinControl. Dalam implementasi pemrograman, kita akan sering berhubungan dengan
kelas-kelas tersebut.
TObject merupakan kelas terdasar dan merupakan dasar dari semua kelas yang ada.
Kelas ini mengenkapsulasi tingkah laku fundamental dari seluruh objek VCL/CLX
dengan memperkenalkan method yang melakukan fungsi dasar seperti membuat,
mengatur, dan menghancurkan instans dari suatu objek dengan cara membebaskan
alokasi memori yang digunakan oleh objek tersebut.
Exception menentukan kelas dasar untuk semua kelas yang berkaitan dengan exceptions.
Exception menyediakan suatu antarmuka yang konsisten untuk kondisi kesalahan
program dan memungkinkan aplikasi menangani kesalahan dengan lebih baik.
TPersistent menentukan kelas dasar untuk semua objek yang mengimplementasikan
property. Kelas yang mewarisi kelas ini berhubungan dengan pengiriman data melalui
stream dan memungkinkan untuk kelas assignment.
TComponent merupakan kelas dasar untuk untuk semua komponen nonvisual, misalnya
TApplication. Kelas ini memungkinkan sebuah komponen tampak pada palet komponen,
memungkinkan komponen berada dalam komponen lainnya, dan dapat dimanipulasi
langsung di atas form.
TControl mewakili kelas dasar untuk semua control atau komponen yang tampak pada
saat program berjalan.
TWinControl menentukan kelas dasar untuk semua windows gadget (widget), di mana
semua komponen yang merupakan turunan dari kelas ini dapat menangkap masukan dari
keyboard.
Faktor ketiga yang harus dikuasai adalah memahami konsep Object Oriented
Programming, pemrograman berorientasi objek. Mengapa? Karena struktur komponen
disusun dari kelas-kelas. Karena representasi dari kelas adalah objek, maka ketika kita
berbicara mengenai komponen, kita juga berbicara mengenai objek. Jika kita
memprogram untuk membuat komponen, maka kita harus menguasai pemrograman yang

berorientasi pada objek.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 6
2 Object Oriented Programming (OOP)
2.1 Apa itu OOP?

O
OP atau Object Oriented Programming (Pemrograman Berorientasi Objek)
merupakan suatu bentuk pemrograman yang memodelkan masalah dengan
pendekatan objek. Dalam bukunya yang berjudul An Introduction to
Object Oriented Programming, Timothy Budd mengutip karakteristik fundamental OOP
dari Alan Kay (yang dianggap oleh sebagian orang sebagai bapak OOP), adalah sebagai
berikut [Budd]:
1. Semua adalah objek.
2. Komputasi dilakukan dengan komunikasi antarobjek. Setiap objek berkomunikasi
dengan objek yang lain melalui pengiriman dan penerimaan pesan. Sebuah pesan
merupakan permintaan atas sekumpulan aksi dengan semua argumen yang
diperlukan untuk menyelesaikan suatu tugas tertentu.
3. Setiap objek memiliki memori sendiri, yang dapat terdiri dari objek-objek lainnya.
4. Setiap objek adalah wakil atau representasi dari suatu kelas. Sebuah kelas dapat
mewakili sekelompok objek yang sama
5. Kelas merupakan kumpulan tingkah laku yang berkaitan dengan sebuah objek.
Jadi, semua objek yang merupakan wakil dari kelas yang sama dapat melakukan
aksi yang sama pula.
6. Kelas-kelas diorganisasi ke dalam struktur pohon yang berakar tunggal,
dinamakan jenjang pewarisan (inheritance hierarchy). Memori dan tingkah laku
yang berkaitan dengan wakil dari sebuah kelas secara otomatis tersedia pada tiap
kelas yang berasosiasi dengan sebuah turunan dalam struktur pohon ini. Jenjang
ini bisa juga dipandang sebagai jenjang piramida, dengan kelas super atau kelas
utama menduduki peringkat teratas dari semua kelas turunannya.

Kelas Tertinggi

Kelas Terendah
Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta
Halaman 7
Sifat kelas pada tingkat tertinggi terbawa hingga ke kelas pada tingkatan yang paling
rendah, yang menunjukkan konsep pewarisan atau inheritance
Dengan menginstruksikan tugas khusus dan terbatas pada setiap objek, programmer dapat
memecah masalah pemrograman menjadi bagian-bagian kecil sehingga dapat mengatasi
kompleksitas permasalahan dengan lebih mudah. Setiap objek pada umumnya memiliki
tiga sifat, yaitu keadaan, operasi, dan identitas objek ([Horstmann] hal. 1). Sebuah objek
dapat menyimpan informasi sebagai hasil operasi sebelumnya. Informasi tersebut
menentukan bagaimana objek melakukan operasi selanjutnya. Koleksi dari seluruh
informasi yang dimiliki objek pada suatu saat merupakan keadaan objek pada saat itu.
Informasi tersebut pada akhirnya memberikan identitas khusus yang membedakan suatu
objek dengan objek lainnya.

2.2 Apa perbedaan OOP dengan Procedural Programming


Menurut Bjarne Stroustrup dalam sebuah papernya yang berjudul What is
‘‘Object Oriented Programming’’? (1991 revised version) [Stroustrup], paradigma dalam
OOP adalah “Tentukan kelas yang kita inginkan; Lengkapi sederetan operasi untuk setiap
kelas; Tentukan struktur secara eksplisit dengan pewarisan”. Sedangkan procedural
programming berparadigma “Tentukan prosedur yang kita inginkan; Gunakan algoritma
terbaik yang bisa ditemukan.” Procedural programming berorientasi pada aksi, sedangkan
object oriented berorientasi pada objek [Deitel].
Pemrograman terstruktur tradisional terdiri atas perancangan struktur data dan
memanipulasinya dengan fungsi-fungsi dengan suatu cara tertentu yang secara teori bisa
berhenti. Fungsi-fungsi ini yang biasa kita kenal dengan algoritma. Niklaus Wirth,
memberikan judul bukunya Algorithms + Data Structures = Programs. Dari judulnya,
secara tidak langsung beliau mengatakan bahwa algoritma dahulu, struktur data
kemudian. Pada awalnya, pikirkan dahulu bagaimana memanipulasi data, baru
menentukan struktur data apa yang tepat digunakan agar manipulasinya menjadi mudah.
OOP membalik urutan tersebut dengan merancang struktur data di awal, baru kemudian
mencari algoritma terbaik untuk memanipulasi data [Cornell].

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 8
Kata kunci procedural programming adalah dekomposisi masalah menjadi
banyak fungsi. Cara ini cukup efektif untuk masalah kecil dan sederhana, namun untuk
masalah yang jauh lebih besar, pendekatan dengan kelas / objek memberikan manfaat
lebih. Pertama, kelas menyediakan mekanisme pengelompokkan yang memudahkan bagi
kita. Sebuah program yang membutuhkan 2000 fungsi mungkin hanya membutuhkan 100
kelas dengan masing-masing kelas memiliki rata-rata 20 operasi. Kelas menyembunyikan
(mengenkapsulasi) representasi data dari semua kode program kecuali operasinya saja.
Jika sebuah bug program mengacaukan sebuah item data, lebih mudah mencari
penyebabnya di antara 20 operasi daripada di antara 2000 fungsi [Horstmann hal. 13].

Global Data

Fungsi Fungsi
Fungsi
Fungsi

Procedural Programming

method

data
method

method data

method

method

data

method

Object Oriented Programming

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 9
3 Konsep-konsep Dasar OOP

K
arena komponen pada dasarnya adalah objek, maka memahami konsep
OOP jelas merupakan sesuatu yang esensial. Kita akan membahas
secara singkat mengenai hal-hal yang berkaitan dengan OOP sebagai
bekal utama dalam langkah pembuatan komponen yaitu:
− Kelas (class abstraction)
− Enkapsulasi (encapsulation)
− Pewarisan (inheritance)
− Polimorfisme (polymorphism)

3.1 Kelas
Kelas merupakan deskripsi abstrak informasi dan tingkah laku dari sekumpulan
data. Kelas juga dikenal sebagai tipe objek. Karenanya, representasi atau wakil dari suatu
kelas adalah objek kelas tersebut. Sebuah kelas merupakan tipe data yang
mengenkapsulasi data dan operasi pada data dalam suatu unit tunggal. Berbeda dengan
procedural programming yang memisahkan antara data dan fungsi sebagai elemen yang
berbeda.
Suatu kelas mendifinisikan suatu struktur yang terdiri atas data kelas (data field),
prosedur atau fungsi kelas (method), dan sifat kelas (property). Sebuah field pada
dasarnya adalah sebuah variabel bagian dari kelas. Method merupakan semua prosedur
yang berasosiasi dengan kelas tersebut. Ada method yang dipanggil melalui objek dari
kelas, dan ada pula method yang dipanggil melalui kelas itu sendiri (hal ini akan dibahas
lebih lanjut kemudian). Property adalah antarmuka untuk data yang berkaitan dengan
objek dari kelas. Property memiliki cara khusus untuk mengaksesnya, yang dikenal
dengan access specifiers. Di luar objek itu, property tampak pada dasarnya hampir sama
seperti field. Istilah-istilah ini akan dijelaskan secara lebih jelas kemudian.
Setiap objek secara dinamis mengalokasikan sejumlah memori dengan struktur
yang telah ditentukan oleh tipe kelasnya. Setiap objek memiliki salinan yang bersifat
tunggal untuk setiap field yang didefinisikan dalam kelas tersebut. Berbeda halnya

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 10
dengan method, semua objek dari kelas itu berbagi method yang sama. Objek diciptakan
dan dimusnahkan dengan method khusus yang disebut constructor dan destructor.
Variabel bertipe kelas sesungguhnya adalah pointer yang mereferensikan sebuah
objek. Jadi ada lebih dari satu variabel yang dapat merujuk pada objek yang sama. Seperti
halnya pointer yang lain, variabel bertipe kelas dapat menampung nilai nil. Perbedaannya
adalah kita tidak perlu mendereferensikan variabel bertipe kelas untuk mengakses
member dari kelas objek tersebut.

3.2 Enkapsulasi
Istilah enkapsulasi sebenarnya adalah kombinasi data dan fungsionalitas dalam
sebuah unit tunggal sebagai bentuk untuk menyembunyikan detail informasi. Inilah salah
satu konsep dalam OOP yang tidak terdapat pada procedural programming. Tipe data
record pada Pascal atau struct pada C hanya mengumpulkan data namun tidak untuk
fungsi atau operasi. Kelas menyatukan data dengan operasi dalam satu kesatuan. Sebagai
tambahan dalam enkapsulasi, OOP lebih dikarakterisasikan dengan pewarisan
(inheritance) dan polimorfisme (polymorphism). Proses enkapsulasi memudahkan kita
untuk menggunakan sebuah objek dari suatu kelas karena kita tidak perlu mengetahui
segala hal secara rinci. Enkapsulasi menekankan pada antarmuka suatu kelas, atau dengan
kata lain bagaimana menggunakan objek kelas tertentu. Sebuah contoh, kelas Mobil
menyediakan antarmuka fungsi untuk menjalankan mobil tersebut, tanpa kita perlu tahu
komposisi bahan bakar, udara, dan kalor yang diperlukan untuk proses tersebut. Disini
terjadi proses enkapsulasi terhadap rincian bagaimana sebuah mobil dijalankan.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 11
3.3 Pewarisan
Sebuah objek dideskripsikan melalui sebuah kelas. Semua perilaku dari sebuah
objek, dapat diketahui dengan mengenali kelas dari objek yang bersangkutan. Jika kita
tahu bahwa objek “Dodol” adalah sebuah makanan, maka kita tahu bahwa objek itu bisa
kita makan, mengandung zat-zat pembentuknya, dengan sejumlah protein atau mineral,
misalnya. Contoh lain, jika objek “X” adalah sebuah Telepon, maka kita bisa menduga
pasti ada suatu cara yang ada pada objek X tersebut yang dapat kita gunakan untuk
menelpon atau menerima telepon dari orang lain. Sistem OOP memungkinkan kita untuk
mendefinisikan suatu kelas baru dengan mewarisi sifat dari kelas lain yang sudah ada.
Contohnya adalah Dodol Duren, Dodol Melon, dan Dodol Coklat adalah contoh dari
beberapa jenis Dodol dengan rasa yang berbeda-beda. Dalam terminologi OOP, kesemua
Dodol itu dikatakan mewarisi kelas Dodol pada umumnya, misalnya mewarisi bahan
pembuat utama yang sama dengan cara pembuatan yang hampir sama, namun dengan
aroma dan citarasa khusus yang ditambahkan untuk membedakan antara Dodol yang satu
dengan dodol yang lainnya. Dodol Duren, Dodol Melon, dan Dodol Coklat dikatakan sub
kelas dari kelas Dodol, sedangkan kelas Dodol adalah super kelas dari ketiga kelas
tersebut. Semua kelas turunan dari kelas Dodol mewarisi sifat-sifat yang ada pada kelas
Dodol. Kita bisa menambahkan sifat khusus yang ada pada kelas turunan yang tidak ada
pada kelas Dodol itu sendiri. Penurunan sifat ini bisa dilakukan secara bertingkat-tingkat,
sehingga semakin ke bawah maka kelas tersebut menjadi semakin spesifik. Misalnya
kelas Dodol Duren Bangkok Spesial Keju mungkin berukuran lebih besar daripada kelas
Dodol pada umumnya, memiliki rasa Duren Bangkok, dan memiliki rasa keju yang khas
di dalamnya.
Sub kelas memungkinkan kita untuk melakukan spesifikasi detail dan perilaku
khusus dari kelas supernya. Dengan konsep pewarisan, seorang programmer dapat
menggunakan kode yang telah ditulisnya pada kelas super berulang kali pada kelas-kelas
turunannya tanpa harus menulis ulang semua kode-kode itu. Kelas abstrak dapat dibuat
sebagai kelas super yang mendefinisikan perilaku umum, misalnya kelas Makanan. Kelas
Makanan adalah suatu kelas abstrak, yang mendefinisikan sesuatu yang dapat dimakan.
Kelas turunannya misalnya adalah kelas Dodol, kelas Rujak, kelas Nasi Goreng, dan
sebagainya. Kelas Makanan tidak mempunyai bentuk, karena ia adalah kelas abstrak.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 12
Bentuknya menjadi jelas ketika kita membuat kelas turunan yang mewarisi dari kelas
Makanan, misalnya kelas Nasi Goreng.

Contoh kelas turunan dari kelas abstrak “Makanan”

3.4 Polimorfisme

Polimorfisme merupakan kemampuan objek-objek yang berbeda kelas namun terkait


dalam pewarisan untuk merespon secara berbeda terhadap suatu pesan yang sama
[Deitel]. Polmorfisme juga dapat dikatakan kemampuan sebuah objek untuk memutuskan
method mana yang akan diterapkan padanya, tergantung letak objek tersebut pada jenjang
pewarisan [Cornell]. Misalnya kita mempunyai kelas Truk yang memiliki method Jalan,
dengan kelas TrukMini yang merupakan turunan dari kelas Truk, yang juga memiliki
method Jalan. Sebuah objek yang bertipe TrukMini dan memanggil method Jalan, akan
memanggil method Jalan yang terdapat pada kelas TrukMini, dan bukan method Jalan
pada kelas Truk. Proses ini termasuk polimorfisme murni karena
berkaitan dengan jenjang pewarisan, dan dinamakan method overriding.
Polimorfisme yang lain juga dapat berlaku ketika sebuah kelas memiliki
lebih dari satu method yang sama namanya, namun berbeda
signaturenya (berbeda pada jenis atau jumlah parameternya). Misalnya
method Jalan bisa dibuat lebih dari satu, tergantung tipe data parameternya,
misal Jalan dengan parameter kecepatan yang bertipe integer atau bertipe double, atau
bahkan bertipe String. Bentuk ini dikenal dengan method name overloading. Horstmann
memberikan istilah polimorfisme jenis ini dengan ad hoc polymorphism.
Ada beberapa sifat dalam method overriding, yaitu refinement, renaming, dan
replacement. Refinement merupakan jenis overriding dimana kode yang ada dalam
superclass disatukan dengan kode yang ada pada subclass. Renaming merupakan proses

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 13
pengubahan nama dari suatu operasi yang diwarisi tanpa mengubah perilakunya.
Sedangkan replacement merupakan jenis overriding di mana kode yang ada pada
superclass benar-benar digantikan oleh kode yang ada pada turunannya.

4 Disain dan Implementasi Pemrograman Berorientasi


Object dengan Delphi

4.1 Bermula dari Masalah, Diakhiri dengan Solusi Program

S
emuanya bermula dari permasalahan. Sebelum membuat program, ada tiga
langkah utama yang bisa terjadi secara berkesinambungan dan membentuk
daur tertentu setelah kita mendapatkan suatu masalah untuk dipecahkan
dengan program. Pertama, adalah analisis permasalahan itu sendiri. Kedua, kita
melakukan disain bagaimana kita akan memecahkan masalah tersebut. Ketiga, adalah
implementasi disain yang telah kita buat. Terkadang, kita harus kembali ke tahap pertama
dan tahap kedua jika memang diperlukan.

4.1.1 Fase Analisis

Pada fase ini biasanya pemahaman masalah yang masih samar-samar diubah
menjadi deskripsi spesifik yang berisi tentang masalah-masalah yang akan dipecahkan.
Misalnya kita akan membuat sebuah program permainan Halma. Pada fase ini, harus
dijelaskan aturan permainan yang tepat dan tidak mengandung kontradiksi. Jika beberapa
daerah mempunyai aturan permainan Halma yang berbeda-beda, fase ini harus
menghasilkan aturan yang baku dan dijadikan suatu panduan untuk fase selanjutnya. Hal
lain yang harus didokumentasikan adalah bagaimana pemain akan berinteraksi dengan
program. Bagaimana bila akan dibuat versi jaringan, dan bagaimana pula jika dilengkapi
dengan pemain komputer dengan menggunakan teknologi kecerdasan buatan, dan
sebagainya. [Horstmann] pada halaman 5 menekankan bahwa fase ini adalah penjelasan
apa yang harus dilakukan dan bukan bagaimana sesuatu harus dilakukan.

4.1.2 Fase Disain

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 14
Perancang program mulai memecahkan masalah dengan pendekatan objek, yaitu
memetakan permasalahan ke dalam kelas-kelas dan pengelompokkan kelas. Setiap kelas
dinyatakan secara tepat yang berisi atribut-atribut dan semua fungsi yang berkaitan hanya
dengan kelas tersebut. Pada fase ini, detail implementasi belum diputuskan secara pasti.
Misalnya kelas yang bertipe kumpulan, tidak perlu diputuskan apakah nantinya akan
menggunakan HashTable atau Tree tertentu. Bahkan pemilihan bahasa pemrograman
juga bukan masalah yang harus diputuskan pada fase ini. Hasil utama dalam fase ini
adalah rancangan interaksi antarkelas yang mendukung pemrograman berorientasi objek
yang harus dapat diimplementasikan dengan semua bahasa pemrograman apapun yang
mendukung OOP.

4.1.3 Fase Implementasi

Pada fase ini programmer mengubah disain kelas-kelas menjadi untain kode
program ke dalam bahasa pemrograman tertentu yang telah ditentukan. Setelah itu kode-
kode tersebut diuji dan pada akhirnya diintegrasikan menjadi satu solusi program akhir.
Pada beberapa permasalahan yang cukup kompleks untuk dimengerti, adanya
sebuah prototipe program akan sangat membantu bahkan pada fase disain maupun
analisis sekalipun. Dengan adanya prototipe ini, diharapkan banyak gagasan akan muncul
sehingga solusi yang diinginkan benar-benar dapat tercapai.
[Horstmann] mengingatkan agar kita tidak terburu-buru dalam fase analisis dan
disain semata-mata hanya untuk mengejar pembuatan prototipe. Sebaliknya jangan pula
kita ragu-ragu untuk kembali ke fase sebelumnya apabila prototipe benar-benar
memberikan kita gagasan baru dalam memecahkan masalah.

Analisis Disain Implementasi

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 15
4.2 Studi Kasus – Menganalisis, Mendisain, dan
Mengimplementasikan Kelas

Berikut ini kita akan coba untuk membuat kelas-kelas yang berkaitan dengan bangun
datar, seperti persegi panjang, lingkaran, dan segitiga dan semuanya dapat digunakan
untuk menghitung luas dan panjang kelilingnya. Kita akan mencoba untuk menganalisis,
mendisain, dan mengimplementasikan ketiga kelas di atas.

4.2.1 Analisis

− Persegi panjang memiliki atribut


panjang dan lebar
Persegi Panjang − Luas persegi panjang dihitung
dengan jalan mengalikan panjang
dan lebarnya
− Keliling dihitung dari
penjumlahan semua sisinya, yaitu
2 x (panjang + lebar)

− Lingkaran memiliki atribut jari-


jari yang merupakan separuh dari
diameternya
− Luas lingkaran dihitung dengan
Lingkaran jalan mengalikan konstanta Pi
yang nilainya didekati oleh 22/7
dengan kuadrat jari-jarinya
− Keliling dihitung dengan
mengalikan konstanta Pi dengan
diameternya

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 16
− Segitiga memiliki atribut 3 sisi
berupa garis lurus yang
membentuk kurva sederhana
tertutup
Segitiga − Luasnya dihitung dengan nilai
akar dari hasil kali setengah
keliling segitiga yang dikalikan
dengan semua selisih setengah
keliling itu dengan masing-
masing sisinya
− Keliling dihitung dengan
menjumlahkan ketiga sisinya

4.2.2 Disain

Jika kita daftarkan semua operasi dan atribut yang berkaitan dengan masing-masing
bangun datar tersebut maka kita akan dapatkan tabel berikut ini:

Kelas Operasi Atribut


Kelas PersegiPanjang − LuasPersegiPanjang − panjang
(menghitung luas persegi − lebar
panjang)
− KelilingPersegiPanjang
(menghitung keliling persegi
panjang)
Kelas Lingkaran − LuasLingkaran (menghitung luas − jarijari
lingkaran)
− KelilingLingkaran (menghitung
keliling lingkaran)
Kelas Segitiga − LuasSegitiga (menghitung luas − sisi1
segitiga) − sisi2
− KelilingSegitiga (menghitung − sisi3
keliling segitiga)

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 17
Jika kita pisahkan ketiga entitas tersebut, kita akan dapatkan daftar berikut:

Class PersegiPanjang Class Class Segitiga


Lingkaran

Attribute Attribute Attribute


panjang jarijari sisiA, sisiB, sisiC
lebar
Method Method
Method cariLuas cariLuas
cariLuas cariKeliling cariKeliling
cariKeliling

Setelah kita perhatikan, ternyata ditemukan bahwa ketiga kelas tersebut memiliki
dua method yang selalu muncul, yaitu cariLuas dan cariKeliling. Kita bisa
menggunakan konsep inheritance dan generalisation (pewarisan dan generalisasi) untuk
ketiga kelas tersebut. Ketiganya adalah merupakan bangun datar. Kelas yang akan
ditambahkan adalah kelas BangunDatar yang dapat dijadikan kelas dasar untuk ketiga
kelas tersebut. Karena kelas bangun datar sangat luas, dan tidak dapat diketahui
bentuknya, maka kelas bangun datar dapat digolongkan sebagai kelas abstrak. Kelas ini
tidak berguna untuk diinstantiasikan atau dibuat objeknya (jika kita memanggil member
dari kelas abstrak, akan menimbulkan exception EAbstractError) untuk komponen yang
mengandung method abstract tidak bisa dibuat instancenya. Kelas ini harus diturunkan
terlebih dahulu menjadi kelas yang lebih kongkrit, misalnya kelas Lingkaran,
PersegiPanjang, Segitiga, atau misalnya kelas JajaranGenjang. Pada diagram berikut ini
kita bisa melakukan pull up method, yaitu menarik method yang ada pada suatu kelas dan
meletakkannya pada kelas supernya. Dengan menggunakan kelas abstrak ini, jika suatu
waktu kita akan membuat kelas yang merupakan bangun datar, maka kita dapat
menurunkannya langsung dari kelas abstrak BangunDatar yang telah kita buat. Dan jika
kita tahu ada sebuah kelas merupakan turunan dari kelas BangunDatar, maka kita tahu
persis bahwa kelas tersebut pasti memiliki method/fungsi/operasi cariLuas dan
cariKeliling. Artinya, ada semacam kontrak yang mengatakan bahwa jika sebuah kelas

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 18
mengimplementasikan suatu kelas abstrak, maka kelas tersebut harus memiliki
implementasi dari semua operasi abstrak yang ada pada kelas abstrak yang akan
diimplementasikan.

Abstract Class
BangunDatar

Method
cariLuas
cariKeliling
Lambang pewarisan

Class PersegiPanjang Class Class Segitiga


Lingkaran

Attribute Attribute Attribute


panjang jarijari sisiA, sisiB, sisiC
lebar
Method Method
Method cariLuas cariLuas
cariLuas cariKeliling cariKeliling
cariKeliling

Karena semua method pada kelas BangunDatar bersifat abstract, maka kita juga bisa
membuat BangunDatar sebagai interface. Interface dikenal juga sebagai kelas abstrak
murni. Jika kelas abstrak bisa memiliki sebagian method yang kongkrit dan abstrak, maka
interface hanya memiliki method yang dideklarasikan sebagai abstrak.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 19
4.2.3 Implementasi

Ketika kita jalankan Delphi akan tampak tampilan berikut.

Component Palette

Object TreeView

Form Designer
Object Inspector

Keterangan:
1. Form Designer merupakan wadah (container) yang dijadikan sebagai tempat
untuk meletakkan semua komponen visual yang akan tampak pada program yang
akan kita buat. Pada saat kita buka Delphi pertama kali, otomatis kita akan
mendapatkan sebuah objek dari kelas TForm
2. Component Palette merupakan tempat untuk meletakkan semua komponen yang
siap digunakan pada program delphi kita
3. Object Inspector merupakan panel untuk menginspeksi objek, dengan kata lain
melihat atribut-atribut dari sebuah objek sehingga kita bisa mengubahnya pada
saat design time
4. Object Tree View merupakan panel untuk melihat hirarki objek-objek yang
diletakkan pada form kita. Hal ini akan memudahkan kita untuk memilih objek
yang sulit untuk diklik ketika akan dipilih, dan melihat parent dari sebuah objek.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 20
Untuk membuat kelas-kelas di atas, kita perlu membuat sebuah unit. Langkahnya adalah
sebagai berikut :
1. Klik menu File New Unit

Sebuah program dibangun dari modul-modul kode program yang disebut unit. Setiap unit
disimpan dalam sebuah file terpisah, dan dikompilasi secara terpisah pula. Dengan unit, kita
dapat :
− Membagi program yang besar ke dalam modul-modul, sehingga bisa diedit secara
terpisah
− Membuat library yang bisa digunakan oleh banyak program

− Library yang telah dikompilasi dapat didistribusikan kepada programmer lain, tanpa harus
menyertakan kode program yang kita buat

Pada gambar di atas, pada waktu kita membuat sebuah unit, akan tampak bagian unit
(unit merupakan reserved word atau kata kunci), interface, implementation, dan end.
Nama unit tersebut secara default diberi nama Unit1, yang otomatis akan disimpan dalam
file Unit1.PAS dan setelah dikompilasi akan menghasilkan file Unit1.DCU (delphi
compiled unit). Nama unit harus unik dalam sebuah program, artinya tidak boleh ada dua
unit yang memiliki nama yang sama, meskipun diletakkan dalam folder yang berbeda.
Bagian interface dimulai dari kata kunci interface dan diakhir pada kata kunci
implementation. Dalam bagian ini, kita bisa mendeklarasikan konstanta, tipe data,

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 21
variabel, prosedur, dan fungsi yang tersedia bagi unit lain yang akan menggunakan unit
ini. Bagian interface hanya menyebutkan deklarasi atau prototipenya saja, sedangkan
implementasi dari fungsi atau prosedur diletakkan setelah kata kunci implementation.
Untuk membuat kelas BangunDatar, pertama-tama kita simpan unit1 menjadi
classBangunDatar.PAS, sehingga nama unitnya menjadi classBangunDatar. Konvensi ini
saya pilih untuk menunjukkan bahwa file classBangunDatar.PAS akan berisi kelas
TBangunDatar.

Penjelasan:
− File classBangunDatar.PAS memiliki unit classBangunDatar
− Unit tersebut memiliki sebuah kelas bernama TBangunDatar yang merupakan
turunan dari kelas TObject. Kita bisa saja menuliskan class(TObject) pada contoh
di atas dengan class saja. Sebab jika kita hanya memberikan kata class,
secara default kelas tersebut merupakan turunan dari kelas TObject. Untuk
kejelasan, saya sengaja selalu menggunakan TObject untuk semua kelas turunan
dari kelas TObject
− Kata kunci public menunjukkan bahwa function cariLuas dan
cariKeliling dapat diakses semua unit

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 22
− cariLuas dan cariKeliling adalah fungsi yang mengembalikan tipe data
double, dideklarasikan virtual, artinya dapat dioverride atau implementasinya

dapat diubah oleh kelas turunannya, dan dideklarasikan abstract, artinya tidak
ada implementasinya pada kelas TBangunDatar, dan implementasinya diserahkan
pada kelas turunannya
Perbandingan pada public abstract class BangunDatar extends Object {
public abstract double cariLuas();
pemrograman Java
public abstract double cariKeliling();
(disimpan pada file }

BangunDatar.java)

− jika kita mengimplementasikan kedua fungsi pada unit classBangunDatar, maka


kita akan mendapatkan pesan kesalahan :

Kelas pada Delphi hampir sama dengan Java, pada dasarnya adalah pointer. Compiler
secara otomatis menyembunyikannya, sehingga kita tidak perlu menggunakan operator
pointer. Mengetahui status kelas sebagai pointer pada dasarnya penting ketika kita
membuat fungsi dengan parameter sebuah kelas. Pada umumnya, kita seharusnya

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 23
melalukan kelas by value daripada by reference. Alasannya adalah kelas sudah
merupakan pointer, yang merupakan reference. Melalukan sebuah kelas by reference
sama saja melakukan reference ke reference lainnya. Hal ini berbeda dengan class pada
C++ yang lebih mirip pada tipe data structnya atau seperti record pada pascal, hanya
saja dilengkapi dengan method. Untuk membuat kelas bertipe pointer kita harus
menggunakan operator pointer *.

Untuk menghasilkan kode pada bagian implementasi, kita dapat mengetikkan secara
manual atau meletakkan kursor pada akhir baris prototipe fungsinya, dan menekan
tombol CTRL + SHIFT + C.
Untuk menambahkan akses pada panjang dan lebar dari persegi panjang, kita
perlu memberikan aksesor dan mutator pada variabel panjang dan lebar. Kedua variabel
itu tetap dalam batasan private artinya hanya bisa diakses dari dalam unit tersebut. Ada
dua cara untuk melakukannya di Delphi, yaitu dengan public method untuk aksesor dan

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 24
mutator, atau dengan menggunakan property. Dengan property, kita seolah-olah
memiliki variabel bertipe public, padahal nama property tersebut hanyalah antarmuka
untuk variabel yang bersifat private atau bahkan method yang sifatnya private. Kita lihat
perbedaannya pada contoh berikut:
unit classPersegiPanjang;

interface

uses classBangunDatar;

type
TPersegiPanjang = class(TBangunDatar)
private
FPanjang: double;
// Konvensi variable private pada Delphi diawali dengan F
FLebar: double;
public
function cariLuas:double; override;
function cariKeliling:double; override;
//dengan menggunakan property
property Panjang:double read FPanjang write FPanjang;
property Lebar:double read FLebar write FLebar;
end;

implementation

{ TPersegiPanjang }

function TPersegiPanjang.cariKeliling: double;


begin
Result := 2 * (FPanjang + FLebar);
end;

function TPersegiPanjang.cariLuas: double;


begin
Result := FPanjang * FLebar;
end;

end.

Versi lainnya adalah :

unit classPersegiPanjang;

interface

uses classBangunDatar;

type
TPersegiPanjang = class(TBangunDatar)
private
FPanjang: double;
FLebar: double;
public
function cariLuas:double; override;
function cariKeliling:double; override;
function getPanjang:double;
function getLebar:double;
procedure setPanjang(panjang:double);
procedure setLebar(lebar:double);
end;

implementation

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 25
{ TPersegiPanjang }

function TPersegiPanjang.cariKeliling: double;


begin
Result := 2 * (FPanjang + FLebar);
end;

function TPersegiPanjang.cariLuas: double;


begin
Result := FPanjang * FLebar;
end;

function TPersegiPanjang.getLebar: double;


begin
Result := FLebar;
end;

function TPersegiPanjang.getPanjang: double;


begin
Result := FPanjang;
end;

procedure TPersegiPanjang.setLebar(lebar: double);


begin
FLebar := lebar;
end;

procedure TPersegiPanjang.setPanjang(panjang: double);


begin
FPanjang := panjang;
end;

end.

Alternatif lainnya adalah melakukan kombinasi antara pemanfaatan variabel private dan
method private pada penggunaan property :
type
TPersegiPanjang = class(TBangunDatar)
private
FPanjang: double;
FLebar: double;
procedure setPanjang(panjang:double);
procedure setLebar(lebar:double);
public
function cariLuas:double; override;
function cariKeliling:double; override;
property Panjang:double read FPanjang write setPanjang;
property Lebar:double read FLebar write setLebar;
end;

Keuntungan menggunakan property adalah :


− Pengembang aplikasi dapat mengubah nilai property pada saat design time, tidak
seperti method yang hanya tersedia pada saat run time. Property bisa muncul pada
object inspector, dan nilainya bisa divalidasi begitu diubah, karena read dan write
bisa diikuti method yang bisa memvalidasi nilai yang diberikan pada property
tersebut

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 26
− Property bisa menyembunyikan detail implementasi, hanya dengan melakukan
assignment seperti pada data field biasa, sebenarnya kita bisa melakukan
perhitungan sangat kompleks, yang tersembunyi dari user
− Property bisa virtual, dapat diimplementasikan secara berbeda pada komponen yang
berbeda
Perbandingan pada public class PersegiPanjang extends BangunDatar {
private double panjang;
pemrograman Java private double lebar;

(disimpan pada file public PersegiPanjang(double panjang,


double lebar) {
PersegiPanjang.java) this.panjang = panjang;
this.lebar = lebar;
}
public double cariLuas() {
return panjang * lebar;
}
public double cariKeliling() {
return 2 * (panjang + lebar);
}
public double getLebar() {
return lebar;
}
public void setLebar(double lebar) {
this.lebar = lebar;
}
public double getPanjang() {
return panjang;
}
public void setPanjang(double panjang) {
this.panjang = panjang;
}
}

Saya sendiri lebih menyukai versi final dari kelas PersegiPanjang berikut ini, yang
dilengkapi dengan constructor.
Constructor merupakan method khusus yang digunakan untuk menciptakan dan
menginisialisasikan sebuah objek. Deklarasinya hampir sama dengan procedure atau
function, hanya saja keyword pendahulunya adalah constructor. Meskipun
deklarasinya tidak mengembalikan nilai, namun sebuah constructor mengembalikan
sebuah reference ke objek yang dibuat. Secara konvensional, nama constructor adalah
Create (tidak seperti pada Java atau C++ yang mengharuskan nama constructor sama

dengan nama kelasnya). Semua data field otomatis akan bernilai 0 untuk tipe ordinal,
kosong untuk String, unsassigned untuk Variant, dan nil untuk pointer atau tipe kelas.
Jadi tidak perlu melakukan inisialisasi dengan nilai tersebut pada constructor.
Self adalah pointer ke objek kelas yang bersangkutan, pada C++ dan Java

dikenal dengan this.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 27
Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta
Halaman 28
Versi untuk kelas lingkaran adalah sebagai berikut :

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 29
Versi untuk kelas Segitiga adalah sebagai berikut :

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 30
Mari kita lihat contoh penggunaan kelas-kelas tersebut pada Delphi.
Buat sebuah form dengan tampilan secara teks (View as Text) adalah sebagai berikut:
object formBangunDatar: TformBangunDatar
Left = 223
Top = 264
Width = 600
Height = 188
Caption = 'Percobaan Bangun Datar'
Color = clBtnFace
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Courier New'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 16
object memoOutput: TMemo
Left = 4
Top = 8
Width = 577
Height = 137
TabOrder = 0
end
end

Tampilan secara visual (View as Form) adalah :

unit FormUtama;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ExtCtrls;

type
TformBangunDatar = class(TForm)
memoOutput: TMemo;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
formBangunDatar: TformBangunDatar;

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 31
implementation

uses classBangunDatar, classPersegiPanjang, classLingkaran, classSegitiga;

{$R *.dfm}

procedure TformBangunDatar.FormCreate(Sender: TObject);


var
bangunDatar:TBangunDatar;
begin
bangunDatar := TPersegiPanjang.Create(10, 5);
memoOutput.Lines.Add(Format('Keliling persegi panjang dengan panjang = %d ' +
'dan lebar = %d adalah %g', [10, 5, bangunDatar.cariKeliling]));
memoOutput.Lines.Add(Format('Luas persegi panjang dengan panjang = %d ' +
'dan lebar = %d adalah %g', [10, 5, bangunDatar.cariLuas]));

bangunDatar := TLingkaran.Create(7);
memoOutput.Lines.Add(Format('Keliling lingkaran dengan jarijari = %d ' +
'adalah %g', [7, bangunDatar.cariKeliling]));
memoOutput.Lines.Add(Format('Luas lingkaran dengan jarijari = %d ' +
'adalah %g', [7, bangunDatar.cariLuas]));

bangunDatar := TSegitiga.Create(3, 4, 5);


memoOutput.Lines.Add(Format('Keliling segitiga dengan sisi %d, %d, dan %d ' +
'adalah %g', [3, 4, 5, bangunDatar.cariKeliling]));
memoOutput.Lines.Add(Format('Luas segitiga dengan sisi %d, %d, dan %d ' +
'adalah %g', [3, 4, 5, bangunDatar.cariLuas]));
end;
end.

Ketika program dijalankan, akan tampil seperti berikut:

Sampai tahap ini kita telah mencoba memulai untuk membuat aplikasi di Delphi dengan
pendekatan berorientasi pada Objek. Masih banyak konsep OOP lainnya yang belum
ditemui, dan akan saya jelaskan sedikit demi sedikit sambil learning by example. Jadi
penjelasan akan diberikan ketika dibutuhkan pada saat studi kasus dan ketika dibutuhkan.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 32
5 Membuat Komponen Sederhana

K ini saatnya kita mencoba untuk membuat komponen sederhana dengan Delphi.
Ada beberapa hal yang perlu kita ketahui dalam pembuatan komponen. Pertama-
tama kita perlu tahu bahwa ada beberapa struktur dalam sebuah komponen.

Kita harus dapat membedakan antara kelas dengan komponen. Kelas adalah struktur atau
tipe data dalam Object Pascal, sedangkan komponen adalah sebuah kelas yang dapat
dimanipulasi dalam Delphi Environment.

Struktur dalam sebuah komponen adalah sebagai berikut:


− Properties (seperti yang sudah kita bahas pada bab sebelumnya) dalam sebuah
komponen jika dimasukkan ke dalam seksi published (dalam struktur kelas), akan
muncul pada Object Inspector. Properties ini memungkinkan kita mengakses field
pada objek dari komponen yang bersangkutan, baik secara design time ataupun run
time.
− Method (fungsi atau prosedur dari suatu kelas)
− Events (terjadinya serangkaian aksi yang terjadi sebagai akibat terjadinya suatu aksi
lainnya). Pada dasarnya, events adalah pointer ke sebuah method. Hal ini
memungkinkan kita untuk melakukan assignment pada sebuah event dengan
prosedur yang kita miliki pada saat program sedang berjalan (run time).

Selain itu kita perlu tahu mengenai konsep kepemilikan (ownership) dan juga pewadahan
(parenthood). Sebuah komponen bisa memiliki komponen lainnya. Pemilik sebuah
komponen ditentukan dengan property Owner. Ketika sebuah komponen memiliki
komponen lainnya, komponen tersebut bertanggungjawab membebaskan alokasi memori
komponen yang dimilikinya ketika komponen itu juga sedang dibebaskan alokasi
memorinya. Parenthood hanya dimungkinkan pada komponen turunan dari TWinControl
yang bisa berfungsi sebagai parent (wadah). Komponen parent bertangunggjawab untuk
untuk memanggil method komponen anaknya untuk memaksa mereka menggambar diri

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 33
mereka sendiri. Konsep ini ditentukan melalui property Parent. Sebuah komponen bisa
memiliki Owner dan Parent yang berbeda.

5.1 Langkah-langkah Membuat Komponen

Ada beberapa check list yang perlu kita perhatikan ketika kita membuat komponen
sendiri:
− Apakah komponen yang akan kita buat cukup unik dan akan berguna untuk kita
sendiri atau programmer lain?
− Sudah jelaskah algoritma yang akan kita gunakan nantinya?
− Sudahkah saya melakukan testing untuk komponen tersebut sebelum diletakkan
dalam Palet Komponen?

Lima langkah dasar ketika kita akan membuat komponen di Delphi:


1. Tentukan superclass dari komponen
2. Buat sebuah unit untuk komponen tersebut
3. Tambahkan method, properties, dan event (jika perlu)
4. Uji coba komponen tersebut
5. Daftarkan komponen tersebut ke Delphi Environment
Adalah hal yang tidak kalah pentingnya bagi kita untuk membuat help file untuk
komponen kita. Dalam help tersebut setidaknya ada daftar Properties, Method, dan Event
yang ada dalam komponen yang kita buat, termasuk cara menggunakannya dengan
contoh yang jelas dan mudah. Semakin baik dan lengkap help file yang dibuat untuk
sebuah komponen, maka semakin mudah programmer lain akan menggunakan komponen
tersebut (bukankah itu salah satu tujuan kita ketika membuat komponen sendiri?).

5.1.1 Menentukan Superclass dari Komponen

Jika kita ingin membuat komponen


1. nonvisual (contohnya TTimer), kita membutuhkan superclass TComponent
2. yang tidak memiliki window handle (contohnya TPaintBox), superclassnya
adalah TGraphicControl

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 34
3. yang memiliki window handle (contohnya TCheckBox, TComboBox),

superclassnya adalah TWinControl


4. yang memiliki window handle dan mempunyai kemampuan khusus untuk
menggambar dalam canvas dan memiliki method paint() untuk
menggambarkan penampilan komponen secara khusus, gunakan superclass
TCustomControl
5. untuk memiliki karakteristik dari komponen yang sudah ada, gunakan komponen
dalam komponen palette seperti TEdit, TPanel, TScrollBox, dan
sebagainya.

5.1.2 Membuat Komponen Sederhana Langkah demi Langkah

Sebagai contoh, kita akan membuat komponen yang sangat sederhana, yaitu sebuah
komponen non visual. Idenya adalah membuat sebuah komponen yang:
− bernama TPersegiPanjangSederhana
− memanfaatkan kelas TPersegiPanjang yang sudah dibuat pada bab sebelumnya
− tidak memiliki visualisasi di atas form
− property Panjang dan Lebar harus bisa diakses dari Object Inspector
− Panjang dan Lebar harus lebih dari 0, jika tidak akan berubah secara otomatis
menjadi masing-masing 1 satuan panjang
− Memiliki fungsi untuk mencari luas dan keliling yang bisa digunakan pada saat
run time

Langkah-langkahnya adalah sebagai berikut :


− Buat sebuah project baru, File New Application
− Simpan Project dengan nama KomponenPersegiPanjangSederhana
− Simpan File dengan nama TestForm
− Tambahkan unit classPersegiPanjang dan classBangunDatar yang
sudah dibuat pada bab sebelumnya dengan cara menekan tombol Shift
+ F11 atau menu Project Add to Project

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 35
− atau jika anda tidak ingin melakukan langkah pada nomor 4, anda bisa
membuat dua unit baru dengan jalan memilih menu File New
Unit dan dibuat persis seperti pada contoh bab sebelumnya dan simpan
dengan nama classPersegiPanjang dan classBangunDatar (salin
isinya persis pada contoh)

− Buat sebuah unit baru, simpan dengan nama


classPersegiPanjangSederhana

− Ketikkan pada unit tersebut kode program berikut:

unit classPersegiPanjangSederhana;

interface

uses Classes, classPersegiPanjang;

{
Kita membutuhkan unit Classes karena kita menggunakan
TComponent sebagai superclass komponen
TPersegiPanjangSederhana dan membutuhkan classPersegiPanjang
karena kita membutuhkan sebuah variabel private bertipe
TPersegiPanjang yang dideklarasikan pada unit
classPersegiPanjang.
}

type
TPersegiPanjangSederhana = class(TComponent)
private
persegiPanjang:TPersegiPanjang;

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 36
function GetLebar: double;
function GetPanjang: double;
procedure SetLebar(const Value: double);
procedure SetPanjang(const Value: double);
public
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
function cariLuas:double;
function cariKeliling:double;
published
property Panjang:double read GetPanjang write
SetPanjang;
property Lebar:double read GetLebar write SetLebar;
end;

procedure Register;
{
Prosedure ini digunakan ketika kita akan mendaftarkan
komponen ini ke Palet Komponen

Nama procedure ini harus persis sama dengan di atas, diawali


huruf besar, untuk kompatibilitas dengan C++ Builder yang
case sensitive agar VCL yang dibuat di Delphi bisa digunakan
pada C++ Builder

Deklarasi prosedur ini WAJIB diletakkan pada bagian


interface
}

implementation

uses Dialogs;

procedure Register;
begin
RegisterComponents('Wisnu Widiarta',
[TPersegiPanjangSederhana]);

{
Komponen TPersegiPanjang akan didaftarkan pada komponen
palet pada halaman dengan nama Wisnu Widiarta
}
end;

{
Kita menggunakan unit Dialogs karena kita menggunakan fungsi
showMessage pada implementasi. Perhatikan bahwa uses pada
bagian interface biasanya mengacu pada unit yang mengandung
tipe data yang diperlukan pada waktu deklarasi tipe data,
sedangkan uses setelah implementation mengacu pada
pemanggilan fungsi atau prosedur pada implementasi kelas
}

{ TPersegiPanjangSederhana }

function TPersegiPanjangSederhana.cariKeliling: double;

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 37
begin
Result := persegiPanjang.cariKeliling;
end;

function TPersegiPanjangSederhana.cariLuas: double;


begin
Result := persegiPanjang.cariLuas;
end;

constructor TPersegiPanjangSederhana.Create(AOwner:
TComponent);
var
lebarDefault, panjangDefault:double;
begin
inherited Create(AOwner);

{
Pada umumnya pemanggilan inherited Create di atas
Selalu dilakukan sebelum kita melakukan inisialisasi
data field. Dengan melakukannya, kita memanggil
constructor Create pada superclass, dan memastikan
bahwa semua data pada superclass telah terinisialisasi
dengan baik
}

lebarDefault := 1.0;
panjangDefault := 1.0;
persegiPanjang := TPersegiPanjang.Create(panjangDefault,
lebarDefault);
end;

destructor TPersegiPanjangSederhana.Destroy;
begin
persegiPanjang.Free;
inherited;
{
Pada umumnya pemanggilan inherited pada destructor
Dilakukan setelah kita membebaskan alokasi memori
untuk semua data field kelas kita sendiri
}
end;

function TPersegiPanjangSederhana.GetLebar: double;


begin
Result := persegiPanjang.Lebar;
end;

function TPersegiPanjangSederhana.GetPanjang: double;


begin
Result := persegiPanjang.Panjang;
end;

procedure TPersegiPanjangSederhana.SetLebar(const Value:


double);
begin
if Value <= 0 then
begin

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 38
showMessage('Lebar harus lebih dari 0');
persegiPanjang.Lebar := 1;
end
else
persegiPanjang.Lebar := Value;
end;

procedure TPersegiPanjangSederhana.SetPanjang(const Value:


double);
begin
if Value <= 0 then
begin
showMessage('Panjang harus lebih dari 0');
persegiPanjang.Panjang := 1;
end
else
persegiPanjang.Panjang := Value;
end;

end.

− Berikutnya kita lakukan uji coba dengan menggunakan FormTest


Rename form dari Form1 menjadi formTest
Letakkan 6 instance dari TLabel ke atas form, 2 TEdit, dan 1
TButton

Tampilan secara teks dari form tersebut adalah :


object formTest: TformTest
Left = 381
Top = 286
Width = 381
Height = 170
Caption = 'Test Persegi Panjang'
Color = clBtnFace
Font.Charset = ANSI_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = [fsBold]
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 39
Left = 20
Top = 31
Width = 46
Height = 13
Caption = 'Panjang'
end
object Label2: TLabel
Left = 20
Top = 55
Width = 32
Height = 13
Caption = 'Lebar'
end
object Label3: TLabel
Left = 192
Top = 32
Width = 91
Height = 13
Caption = 'Luasnya adalah '
end
object lblLuas: TLabel
Left = 292
Top = 32
Width = 7
Height = 13
Caption = '1'
end
object Label4: TLabel
Left = 192
Top = 60
Width = 61
Height = 13
Caption = 'Kelilingnya'
end
object lblKeliling: TLabel
Left = 292
Top = 60
Width = 7
Height = 13
Caption = '4'
end
object btnTest: TButton
Left = 20
Top = 88
Width = 141
Height = 25
Caption = 'Buat Persegi Panjang'
TabOrder = 0
OnClick = btnTestClick
end
object edPanjang: TEdit
Left = 76
Top = 28
Width = 81
Height = 21
TabOrder = 1
Text = '1'

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 40
end
object edLebar: TEdit
Left = 76
Top = 52
Width = 81
Height = 21
TabOrder = 2
Text = '1'
end
end

− Pastikan isi dari form test di atas adalah sebagai berikut :


unit TestForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls;

type
TformTest = class(TForm)
btnTest: TButton;
edPanjang: TEdit;
Label1: TLabel;
edLebar: TEdit;
Label2: TLabel;
Label3: TLabel;
lblLuas: TLabel;
Label4: TLabel;
lblKeliling: TLabel;
procedure btnTestClick(Sender: TObject);
private
{ Private declarat0ions }
public
{ Public declarations }
end;

var
formTest: TformTest;

implementation

uses classPersegiPanjangSederhana;

{$R *.dfm}

procedure TformTest.btnTestClick(Sender: TObject);


var
persegiPanjang:TPersegiPanjangSederhana;
begin
persegiPanjang := TPersegiPanjangSederhana.Create(Self);
persegiPanjang.Panjang := StrToFloatDef(edPanjang.Text,
1.0);
persegiPanjang.Lebar := StrToFloatDef(edLebar.Text, 1.0);

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 41
lblLuas.Caption := Format('%g',
[persegiPanjang.cariLuas]);
lblKeliling.Caption := Format('%g',
[persegiPanjang.cariKeliling]);
persegiPanjang.free;
end;

end.

− Setelah kita merasa bahwa uji coba terhadap komponen secara


dynamic seperti yang kita lakukan di atas telah cukup, sekarang kita
coba untuk menginstal komponen ini ke Palet Komponen. Untuk
melakukannya, kita perlu sebuah Package
− Buat sebuah package, Pilih menu File New Other Package
− Simpan (File Save As) dengan nama
PersegiPanjangSederhanaPackage

− Kita perlu membuat ICON untuk komponen ini. Cara yang paling
mudah adalah menggunakan Image Editor (Klik menu Tools Image
Editor)

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 42
− Buat sebuah Component Resource File (DCR) dengan jalan memilih
menu File New Component Resource File (.dcr)

− Pada menu contents, klik kanan dan pilih New Bitmap

− Selalu pilih ukuran 24 x 24 dan VGA (16 Colors) untuk hasil terbaik di
semua komputer

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 43
− Rename nama bitmap menjadi nama komponen yaitu
TPERSEGIPANJANGSEDERHANA (wajib sama!)

− Double klik pada TPERSEGIPANJANGSEDERHANA dan gambar


bitmap untuk komponen ini. Perbesar tampilannya dengan menekan
Ctrl + I atau melakukan Zoom In pada menu View

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 44
− Simpan DCR ini PERSIS SAMA dengan nama unit komponennya,
yaitu classPersegiPanjangSederhana.dcr

Jika nama komponennya TAbc, maka nama bitmap harus TABC


Jika nama unitnya UNITABC.PAS, maka nama file DCRnya harus UNITABC.DCR

− Kembali pada window PACKAGE, tekan tombol Add

− Tekan tombol Browse dan pilih


classPersegiPanjangSederhana.pas

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 45
Secara otomatis classPersegiPanjang.dcr akan otomatis ditambahkan.
− Lakukan hal yang sama untuk classBangunDatar.pas dan
classPersegiPanjang.pas, lalu tekan tombol Compile

Setelah menekan tombol Compile, maka akan tampil konfirmasi sebagai


berikut:

− Tekan tombol install, dan tekan OK

− Selesai, hasilnya bisa dilihat pada palet komponen, pada Page Wisnu
Widiarta

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 46
Berikutnya kita bisa melakukan uji coba pada FormTest seperti kita lihat pada gamber
berikut:

Jika kita memberi nilai negatif pada property Lebar, maka akan muncul pesan bahwa
Lebar harus lebih dari 0, dan property Lebar ini akan diberi nilai 1. Hal yang sama
berlaku untuk property Panjang.
Sebagian besar upaya untuk membuat komponen lebih kurang seperti pada
langkah-langkah di atas. Berikutnya kita akan lihat pembuatan komponen-komponen
lainnya sebagai bahan latihan. Beberapa materi dan informasi baru akan disertakan
setahap demi setahap.

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 47
6 Contoh Komponen-Komponen
6.1 Komponen yang Terhubung ke Basisdata
6.1.1 TWWDBNavigator

Ketika membuat aplikasi basisdata, kita sering menggunakan komponen data aware,
yang biasanya terletak pada palet komponen bagian Data Control. Salah satu komponen
yang paling sering digunakan adalah TDBNavigator, digunakan untuk menavigasi ketika
kita akan memanipulasi suatu tabel. Waktu saya menggunakan komponen ini, terkadang
ingin sekali bisa mengganti icon yang ada dengan icon yang saya miliki sendiri. Kadang
pula saya menginginkan komponen navigasi tersebut dapat memiliki Caption sehingga
lebih memudahkan bagi pengguna dalam menggunakan komponen tersebut. Dengan
berbekal nekad dan tekad bulat, akhirnya saya memberanikan diri untuk mempelajari
kode program TDBNavigator, dan berusaha memodifikasinya. Tentu saja hasilnya masih
bisa untuk disempurnakan. Idenya adalah sebagai berikut:
− Membuat TDBNavigator yang bisa diganti-ganti iconnya
− Bisa diberi Caption, dalam bahasa Indonesia maupun bahasa Inggris
− Caption bisa muncul bisa tidak, seperti halnya dengan icon
− Ketika menekan tombol tambah atau hapus, harus ada event yang tertrigger
sebelum perintah insert atau delete dilakukan ke tabel (karena event OnClick
pada TDBNavigator bawaan Delphi terpicu setelah perintah tersebut dilakukan.
Dan terkadang, kita perlu melakukan sesuatu sebelum benar-benar menghapus
atau menambah data. Misalnya untuk memeriksa apakah boleh menghapus atau
menambah data)

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 48
Kita lihat pada gambar sebelumnya, enam komponen navigasi di atas menunjukkan:
1. Navigator berbahasa Indonesia
2. Navigator berbahasa Inggris
3. Navigator tanpa caption, hanya icon
4. Navigator dengan caption dan icon, posisi caption di sebelah kanan
5. Navigator dengan caption dan icon, posisi caption di sebelah bawah
6. Navigator bawaan Delphi (TDBNavigator)

Berikut ini adalah listing program dari TWWDBNavigator:

unit classWWDBNavigator;

{*********************************************************************
* Nama program : WWDBNavigator *
* Deskripsi : Membuat komponen yang mirip dengan DBNavigator *
* dilengkapi dengan Caption dan Glyph sekaligus *
* Tanggal : 14 September 2002 *
* Revisi akhir : 24 Oktober 2005 *
* Programmer : Wisnu Widiarta *
* *
**********************************************************************}

interface

uses
Windows, Messages, SysUtils, Classes, Controls, ExtCtrls, Buttons,
Dialogs,
Variants, ImgList, Db;

type
TWWBtnKind = (wbkFirst, wbkPrior, wbkNext, wbkLast, wbkInsert,
wbkDelete,
wbkEdit, wbkPost, wbkCancel, wbkRefresh);
{ TWWBtnKind merupakan tipe enumerasi yang mewakili fungsi masing-
masing
tombol }

TBtnNavigator = array[TWWBtnKind] of TSpeedButton;


{ array yang terdiri dari TSpeedButton untuk navigasi }

TVisibleButtons = set of TWWBtnKind;


{ himpunan tombol yang akan dimunculkan }

TNavigatorEventClick = procedure (Sender:TObject; wbtnKind:TWWBtnKind)


of Object;

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 49
{ event yang akan ditrigger ketika tombol diklik }

TWWDBNavigator = class;
{ forward declaration, untuk menunjukkan bahwa TWWDBNavigator adalah
sebuah
kelas }

{ TWWDataLink }

TWWDataLink = class(TDataLink)
private
FNavigator: TWWDBNavigator;
protected
procedure EditingChanged; override;
procedure DataSetChanged; override;
procedure ActiveChanged; override;
public
constructor Create(ANav: TWWDBNavigator);
destructor Destroy; override;
end;

{ kelas TDataLink merupakan kelas pembantu yang digunakan objek untuk


database
agar terbentuk koordinasi antara aksi pada TDataSource dan TDataSet,
dan
tanggap untuk event data }

{ TWWDBnavigator }
TWWDBNavigator = class(TPanel)
private
{ Private declarations }

FBtnNavigators:TBtnNavigator; { tombol yang dipakai }


FButtonHeight:integer; { tinggi masing-masing tombol }
FButtonWidth:integer; { lebar masing-masing tombol }
FCaptions:TStrings; { caption untuk masing-masing tombol }
FConfirmDelete:Boolean; { apakah ada konfirmasi ketika akan
menghapus data }
FDataLink:TWWDataLink; { untuk mengatur data link }
FDeleteRecordQuestion:String; { pertanyaan untuk konfirmasi ketika
akan menghapus }
FHeight:integer; { tinggi panel tempat tombol }
FHints:TStrings; { Tool tip untuk masing-masing tombol }
FImageChangeLink: TChangeLink; { Perubahan pada gambar }
FImages:TCustomImageList; { Kumpulan gambar / glyph untuk icon }
FLayout:TButtonLayout; { layout dari masing-masing tombol }
FOnNavigatorClick:TNavigatorEventClick; { event yang akan dipicu }
FWidth:integer; { lebar panel }
FVisibleButtons:TVisibleButtons; { tombol yang tampil }
FFlat: boolean; { apakah tombol bersifat flat atau tidak }
FOnBeforeDatabaseEvent: TNavigatorEventClick; { event sebelum aksi
database dilakukan }
FIndonesianLanguage: boolean; { apakah menggunakan bahasa Indonesia
/ Inggris }
FCaptionEnabled: boolean; { apakah caption digunakan atau tidak }

procedure ImageListChange(Sender: TObject); { ketika gambar diubah }

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 50
procedure ClearButton; { menghapus semua tombol }
procedure CMEnabledChanged(var Message: TMessage); message
CM_ENABLEDCHANGED;
{ketika enabled berubah }
procedure DoNavigatorClick(Sender:TObject; btnKind:TWWBtnKind);
{ prosedur untuk menjalankan event }
procedure DoNavigatorResize(Sender:TObject);
{ prosedur ketika navigator berubah ukuran }

procedure RedrawButton; { menggambar ulang tombol }


procedure SetButtonHeight(aHeight:integer); { mengatur tinggi tombol
}
procedure SetButtonWidth(aWidth:integer); { mengatur lebar tombol }
procedure SetCaptions(value:TStrings); { mengatur caption tombol }
procedure SetDeleteRecordQuestion(aQuestion:String);
{ mengatur pertanyaan ketika akan menghapus }
procedure SetHeight(aHeight:integer); { mengatur tinggi panel }
procedure SetHints(value:TStrings); { mengatur tool tip }
procedure SetImages(Value: TCustomImageList); { mengatur icon }
procedure SetLayout(aLayout:TButtonLayout); { mengatur layout }
procedure SetDataSource(aDataSource:TDataSource); { mengatur
DataSource }
procedure SetVisibleButtons(value:TVisibleButtons); { mengatur
tombol yang muncul }
procedure SetWidth(aWidth:integer); { mengatur lebar panel }

function VisibleButtonCount:integer; { menghitung jumlah tombol yang


tampil }
function GetDataSource:TDataSource; { menentukan data source }

procedure OnButtonClick(Sender:TObject); { event ketika tombol


diklik }
procedure OnCaptionsChange(Sender:TObject); { ketika caption diubah
}
procedure OnHintsChange(Sender:TObject); { ketika tool tip diubah }
procedure SetFlat(const Value: boolean); { mengatur tombol flat atau
tidak }
procedure SetIndonesianLanguage(const Value: boolean); { mengatur
bahasa }
procedure SetCaptionEnabled(const Value: boolean); { mengatur
caption akan dimunculkan atau tidak }

protected
{ Protected declarations }
procedure ActiveChanged;
procedure EditingChanged;
procedure DataChanged;
procedure Notification(AComponent: TComponent; Operation:
TOperation); override;
{ keempat prosedur di atas diadaptasi dari versi TDBNavigator untuk
menangkap
perubahan data dan Notification (turunan dari TComponent) }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 51
{ Published declarations }
property ButtonHeight : integer read FButtonHeight write
SetButtonHeight;
property ButtonWidth : integer read FButtonWidth write
SetButtonWidth;
property Caption : TStrings read FCaptions write SetCaptions;
property ConfirmDelete : boolean read FConfirmDelete write
FConfirmDelete;
property DataSource : TDataSource read GetDataSource write
SetDataSource;
property DeleteRecordQuestion : String read FDeleteRecordQuestion
write SetDeleteRecordQuestion;
property Flat : boolean read FFlat write SetFlat;
property Height : integer read FHeight write SetHeight;
property Hints : TStrings read FHints write SetHints;
property Images : TCustomImageList read FImages write SetImages;
property Layout : TButtonLayout read FLayout write SetLayout;
property VisibleButtons:TVisibleButtons read FVisibleButtons write
SetVisibleButtons;
property Width : integer read FWidth write SetWidth;
property IndonesianLanguage : boolean read FIndonesianLanguage write
SetIndonesianLanguage;
property CaptionEnabled : boolean read FCaptionEnabled write
SetCaptionEnabled;

property OnClick : TNavigatorEventClick read FOnNavigatorClick write


FOnNavigatorClick;
property OnBeforeDatabaseEvent : TNavigatorEventClick read
FOnBeforeDatabaseEvent write FOnBeforeDatabaseEvent;
{ ditrigger sebelum aksi database dilakukan }
end;

procedure Register;

implementation

uses StdCtrls,
classIndonesianDialog { untuk menampilkan konfirmasi berbahasa
Indonesia };

procedure Register;
begin
RegisterComponents('Wisnu Widiarta', [TWWDBNavigator]);
end;

Constructor TWWDBNavigator.Create(AOwner:TComponent);
var
i:integer;
msg:array[TWWBtnKind] of String;
begin
inherited Create(AOwner);

ControlStyle := ControlStyle - [csAcceptsControls, csSetCaption] +


[csOpaque];
{ - Kita tidak ingin ada komponen yang bisa diletakkan di atas

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 52
DBNavigator, jadi control stylenya kita hilangkan yaitu
csAcceptsControls
- csSetCaption kita hilangkan karena kita tidak ingin nama
komponen menjadi caption
- csOpaque kita masukkan karena kita ingin control memenuhi
kotak client }

FHints := TStringList.Create;
if Fhints.Count = 0 then
with FHints do
begin
Add('First record');
Add('Previous record');
Add('Next record');
Add('Last record');
Add('Insert record');
Add('Delete record');
Add('Edit record');
Add('Save record');
Add('Cancel record');
Add('Refresh record');
end;
TStringList(FHints).OnChange := OnHintsChange;
{ melakukan assignment event saat run time }

FCaptions := TStringList.Create;
if FCaptions.Count = 0 then
begin
msg[wbkFirst] := 'First';
msg[wbkPrior] := 'Prior';
msg[wbkNext] := 'Next';
msg[wbkLast] := 'Last';
msg[wbkInsert] := 'Insert';
msg[wbkDelete] := 'Delete';
msg[wbkPost] := 'Save';
msg[wbkCancel] := 'Cancel';
msg[wbkRefresh] := 'Refresh';
msg[wbkEdit] := 'Edit';

for i:=Ord(Low(FBtnNavigators)) to Ord(High(FBtnNavigators))


do
FCaptions.Add(msg[TWWBtnKind(i)]);
end;
TStringList(FCaptions).OnChange := OnCaptionsChange;

for i:=Ord(wbkFirst) to Ord(wbkRefresh) do


begin
FBtnNavigators[TWWBtnKind(i)] := TSpeedButton.Create(Self);
with FBtnNavigators[TWWBtnKind(i)] do
begin
Parent := Self;
Left := i * Width;
Top := 0;
TabStop := False;
Tag := i;
Caption := FCaptions[i];
Hint := FHints.Strings[i];

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 53
OnClick := OnButtonClick;
end;
end;

if (csDesigning in ComponentState) then


begin
FVisibleButtons := [wbkFirst, wbkPrior, wbkNext, wbkLast,
wbkInsert, wbkDelete, wbkEdit,
wbkPost, wbkCancel, wbkRefresh];
{ ketika komponen sedang berada pada form dan dimanipulasi,
yang tampak adalah semua tombol }
end;

OnResize := DoNavigatorResize;
BevelInner := bvNone;
BevelOuter := bvNone;

FImageChangeLink := TChangeLink.Create;
FImageChangeLink.OnChange := ImageListChange;

FDataLink := TWWDataLink.Create(Self);

FCaptionEnabled := True;
end;

procedure TWWDBNavigator.ActiveChanged;
var
I: TWWBtnKind;
begin
if not (Enabled and FDataLink.Active) then
for I := Low(FBtnNavigators) to High(FBtnNavigators) do
FBtnNavigators[I].Enabled := False
else
begin
DataChanged;
EditingChanged;
end;
end;

procedure TWWDBNavigator.CMEnabledChanged(var Message: TMessage);


begin
inherited;
if not (csLoading in ComponentState) then
ActiveChanged;
{ csLoading terjadi ketika komponen sedang di-load }
end;

procedure TWWDBNavigator.DataChanged;
var
UpEnable, DnEnable: Boolean;
begin
UpEnable := Enabled and FDataLink.Active and not
FDataLink.DataSet.BOF;
DnEnable := Enabled and FDataLink.Active and not
FDataLink.DataSet.EOF;
FBtnNavigators[wbkFirst].Enabled := UpEnable;
FBtnNavigators[wbkPrior].Enabled := UpEnable;

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 54
FBtnNavigators[wbkNext].Enabled := DnEnable;
FBtnNavigators[wbkLast].Enabled := DnEnable;
FBtnNavigators[wbkDelete].Enabled := Enabled and FDataLink.Active
and
FDataLink.DataSet.CanModify and
not (FDataLink.DataSet.BOF and FDataLink.DataSet.EOF);
end;

procedure TWWDBNavigator.DoNavigatorClick(Sender:TObject;
btnKind:TWWBtnKind);
begin
if Assigned(FOnNavigatorClick) then
FOnNavigatorClick(Self, btnKind);
{ ketika tombol diklik }
end;

procedure TWWDBNavigator.EditingChanged;
var
CanModify: Boolean;
begin
CanModify := Enabled and FDataLink.Active and
FDataLink.DataSet.CanModify;
FBtnNavigators[wbkInsert].Enabled := CanModify;
FBtnNavigators[wbkEdit].Enabled := CanModify and not
FDataLink.Editing;
FBtnNavigators[wbkPost].Enabled := CanModify and FDataLink.Editing;
FBtnNavigators[wbkCancel].Enabled := CanModify and
FDataLink.Editing;
FBtnNavigators[wbkRefresh].Enabled := CanModify;
end;

function TWWDBNavigator.GetDataSource:TDataSource;
begin
Result := FDataLink.DataSource;
end;

procedure TWWDBNavigator.SetDataSource(aDataSource:TDataSource);
begin
FDataLink.DataSource := aDataSource;
if not (csLoading in ComponentState) then
ActiveChanged;
if aDataSource <> nil then aDataSource.FreeNotification(Self);
end;

procedure TWWDBNavigator.ImageListChange(Sender: TObject);


begin
ClearButton;
RedrawButton;
{ ketika image icon diubah, buang semua gambar, lalu gambar ulang }
end;

procedure TWWDBNavigator.Notification(AComponent: TComponent;


Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (Operation = opRemove) and (FDataLink <> nil) and
(AComponent = DataSource) then

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 55
DataSource := nil;
end;

procedure TWWDBNavigator.OnButtonClick(Sender:TObject);
var
index:TWWBtnKind;
begin
Self.SetFocus;
index := TWWBtnKind((Sender as TSpeedButton).Tag);

if (DataSource <> nil) and (DataSource.State <> dsInactive) then


begin
if not (csDesigning in ComponentState) and
Assigned(FOnBeforeDatabaseEvent) then
FOnBeforeDatabaseEvent(Self, index);
{ picu event OnBeforeDatabaseEvent sebelum melakukan suatu
aksi apapun }

with DataSource.DataSet do
begin
case Index of
wbkPrior: Prior;
wbkNext: Next;
wbkFirst: First;
wbkLast: Last;
wbkInsert: Insert;
wbkEdit: Edit;
wbkCancel: Cancel;
wbkPost: Post;
wbkRefresh: Refresh;
wbkDelete:
if FIndonesianLanguage then
begin
if (not FConfirmDelete) or

(TIndonesianDialog.MessageDlg(FDeleteRecordQuestion, mtConfirmation,
mbOKCancel) <> mrCancel) then Delete;
end
else
begin
if (not FConfirmDelete) or
(MessageDlg(FDeleteRecordQuestion,
mtConfirmation, mbOKCancel, 0) <> mrCancel) then Delete;
end;
end;
end;
end;
if not (csDesigning in ComponentState) and
Assigned(FOnNavigatorClick) then
DoNavigatorClick(Self, index);

{ baru lakukan aksi ketika diklik }


end;

procedure TWWDBNavigator.OnHintsChange(Sender:TObject);
var
i:integer;

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 56
begin
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
begin
with FBtnNavigators[TWWBtnKind(i)] do
if i < FHints.Count then
Hint := FHints.Strings[i]
else
Hint := '';
end;
end;

procedure TWWDBNavigator.OnCaptionsChange(Sender:TObject);
var
i:integer;
begin
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
begin
with FBtnNavigators[TWWBtnKind(i)] do
if i < FCaptions.Count then
begin
if FCaptionEnabled then
Caption := FCaptions.Strings[i]
else
Caption := '';
end
else
Caption := '';
end;
end;

function TWWDBNavigator.VisibleButtonCount:integer;
var
i:TWWBtnKind;
begin
Result := 0;
for i:=wbkFirst to wbkRefresh do
if i in FVisibleButtons then
Inc(Result);
end;

procedure TWWDBNavigator.SetButtonWidth(aWidth:integer);
var
i, leftPos:integer;
begin
if VisibleButtonCount > 0 then
aWidth := inherited Width div VisibleButtonCount
else
aWidth := inherited Width div 10;

if aWidth < 1 then


Raise Exception.Create('TWWDBNavigator: minimum value for this
property is 1.')
else
begin
leftPos := 0;
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
begin

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 57
with FBtnNavigators[TWWBtnKind(i)] do
begin
Visible := TWWBtnKind(i) in FVisibleButtons;
if Visible then
begin
Width := aWidth;

Left := LeftPos;
LeftPos := LeftPos + aWidth;
end;
end;
end;

FButtonWidth := aWidth;
if Self.VisibleButtonCount > 0 then
Width := FBtnNavigators[TWWBtnKind(0)].Width *
Self.VisibleButtonCount;
end;
end;

procedure TWWDBNavigator.SetButtonHeight(aHeight:integer);
var
i:integer;
begin
if aHeight < 1 then
Raise Exception.Create('TWWDBNavigator: minimum value for this
property is 1.')
else
begin
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
begin
with FBtnNavigators[TWWBtnKind(i)] do
begin
Visible := TWWBtnKind(i) in FVisibleButtons;
Height := aHeight;
end;
end;

FButtonHeight := aHeight;
Height := aHeight;
end;
end;

procedure TWWDBNavigator.SetCaptions(value:TStrings);
var
i:integer;
begin
FCaptions.Assign(value);
if value <> nil then
begin
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
begin
with FBtnNavigators[TWWBtnKind(i)] do
if i < FCaptions.Count then
Caption := FCaptions.Strings[i]
else
Caption := '';

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 58
end;
end;
end;

procedure TWWDBNavigator.SetDeleteRecordQuestion(aQuestion:String);
begin
if Trim(aQuestion) = '' then
begin
if ConfirmDelete = True then
FDeleteRecordQuestion := 'Do you want to delete this
record?'
else
FDeleteRecordQuestion := '';
end
else
FDeleteRecordQuestion := aQuestion;
end;

procedure TWWDBNavigator.SetHints(value:TStrings);
var
i:integer;
begin
FHints.Assign(value);
if value <> nil then
begin
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
begin
with FBtnNavigators[TWWBtnKind(i)] do
if i < FHints.Count then
Hint := FHints.Strings[i]
else
Hint := '';
end;
end;
end;

procedure TWWDBNavigator.SetWidth(aWidth:integer);
var
i, leftPos:integer;
begin
if aWidth < 1 then
Raise Exception.Create('TWWDBNavigator: minimum value for this
property is 1.')
else
begin
leftPos := 0;
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
begin
with FBtnNavigators[TWWBtnKind(i)] do
begin
Visible := TWWBtnKind(i) in FVisibleButtons;
if Visible then
begin
Left := leftPos;
Width := aWidth div Self.VisibleButtonCount;
leftPos := leftPos + Width;
end;

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 59
end;
end;

if Self.VisibleButtonCount > 0 then


begin
FButtonWidth := aWidth div Self.VisibleButtonCount;
FWidth := FButtonWidth * Self.VisibleButtonCount;
inherited width := FWidth;
end
else
begin
inherited width := aWidth;
FWidth := aWidth;
end;

end;
end;

procedure TWWDBNavigator.SetHeight(aHeight:integer);
var
i:integer;
begin
if aHeight < 1 then
Raise Exception.Create('TWWDBNavigator: minimum value for this
property is 1.')
else
begin
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
with FBtnNavigators[TWWBtnKind(i)] do
begin
Visible := TWWBtnKind(i) in FVisibleButtons;
Height := aHeight;
end;

FHeight := aHeight;
FButtonHeight := aHeight;
inherited Height := aHeight;
end;
end;

procedure TWWDBNavigator.SetVisibleButtons(value:TVisibleButtons);
var
i, leftPos, shouldBeVisibleCount:integer;
begin
leftPos := 0;
FVisibleButtons := value;

shouldBeVisibleCount := 0;
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
begin
if TWWBtnKind(i) in value then
inc(shouldBeVisibleCount);
end;

for i:=Ord(wbkFirst) to Ord(wbkRefresh) do


begin
with FBtnNavigators[TWWBtnKind(i)] do

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 60
begin
Visible := TWWBtnKind(i) in value;
if Visible then
begin
Width := inherited width div shouldBeVisibleCount;
Height := FButtonHeight;

Left := LeftPos;
LeftPos := LeftPos + FButtonWidth;

if (csDesigning in ComponentState) then


begin
Top := 0;
BringToFront;
end;
end
else
begin
if (csDesigning in ComponentState) then
begin
Top := FButtonHeight;
SendToBack;
end;
end;
end;
end;

if Self.VisibleButtonCount > 0 then


Width := (inherited width div shouldBeVisibleCount) *
shouldBeVisibleCount
else
inherited Width := FButtonWidth;

if Not (csDesigning in ComponentState) then


Invalidate;
end;

procedure TWWDBNavigator.RedrawButton;
var
i:integer;
begin
if Assigned(FImages) then
begin
i := 0;
while (i <= ord(wbkRefresh)) and (i < FImages.Count) do
begin
FImages.GetBitmap(i,
FBtnNavigators[TWWBtnKind(i)].Glyph);
Inc(i);
end;
Self.Invalidate;
end
else ClearButton;
end;

procedure TWWDBNavigator.ClearButton;
var

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 61
i:integer;
begin
i := 0;
while (i <= ord(wbkRefresh)) do
begin
FBtnNavigators[TWWBtnKind(i)].Glyph := Nil;
Inc(i);
end;
Invalidate;
end;

procedure TWWDBNavigator.SetImages(Value: TCustomImageList);


begin
if FImages <> nil then FImages.UnRegisterChanges(FImageChangeLink);
FImages := Value;
if FImages <> nil then
begin
ClearButton;
FImages.RegisterChanges(FImageChangeLink);
FImages.FreeNotification(Self);
RedrawButton;
end
else
ClearButton;
end;

procedure TWWDBNavigator.SetLayout(aLayout:TButtonLayout);
var
i:TWWBtnKind;
begin
for i:=Low(FBtnNavigators) to High(FBtnNavigators) do
FBtnNavigators[i].Layout := aLayout;
FLayout := aLayout;
end;

procedure TWWDBNavigator.DoNavigatorResize(Sender:TObject);
vaR
leftPos, i:integer;
begin
Width := inherited Width;
Height:= inherited Height;

leftPos := 0;

for i:=Ord(wbkFirst) to Ord(wbkRefresh) do


begin
with FBtnNavigators[TWWBtnKind(i)] do
begin
Visible := TWWBtnKind(i) in FVisibleButtons;
if Visible then
begin
Width := FButtonWidth;
Height := FButtonHeight;

Left := LeftPos;
LeftPos := LeftPos + FButtonWidth;
end

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 62
end;
end;
end;

destructor TWWDBNavigator.Destroy;
var
i:integer;
begin
for i:=Ord(wbkFirst) to Ord(wbkRefresh) do
FBtnNavigators[TWWBtnKind(i)].Free;

FHints.Free;
FCaptions.Free;
FDataLink.Free;
FDataLink := Nil;
inherited Destroy;
end;

{ TWWDataLink }
constructor TWWDataLink.Create(ANav: TWWDBNavigator);
begin
inherited Create;
FNavigator := ANav;
VisualControl := True;
end;

procedure TWWDataLink.EditingChanged;
begin
if FNavigator <> nil then FNavigator.EditingChanged;
end;

procedure TWWDataLink.DataSetChanged;
begin
if FNavigator <> nil then FNavigator.DataChanged;
end;

procedure TWWDataLink.ActiveChanged;
begin
if FNavigator <> nil then FNavigator.ActiveChanged;
end;

destructor TWWDataLink.Destroy;
begin
FNavigator := nil;
inherited Destroy;
end;

procedure TWWDBNavigator.SetFlat(const Value: boolean);


var
i:TWWBtnKind;
begin
FFlat := Value;
for i:=Low(FBtnNavigators) to High(FBtnNavigators) do
FBtnNavigators[i].Flat := Value;
end;

procedure TWWDBNavigator.SetIndonesianLanguage(

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 63
const Value: boolean);
var
msg:array[TWWBtnKind] of String;
newHints:TStringList;
i:integer;
begin
FIndonesianLanguage := Value;

newHints := TStringList.Create;
if value then
begin
with newHints do
begin
Add('Awal data');
Add('Data sebelumnya');
Add('Data berikutnya');
Add('Akhir data');
Add('Tambah data');
Add('Hapus data');
Add('Edit data');
Add('Simpan data');
Add('Batalkan perubahan');
Add('Baca ulang data');
end;

SetHints(newHints);

msg[wbkFirst] := 'Awal';
msg[wbkPrior] := 'Maju';
msg[wbkNext] := 'Mundur';
msg[wbkLast] := 'Akhir';
msg[wbkInsert] := 'Tambah';
msg[wbkDelete] := 'Hapus';
msg[wbkPost] := 'Simpan';
msg[wbkCancel] := 'Batal';
msg[wbkRefresh] := 'Baca Ulang';
msg[wbkEdit] := 'Edit';
end
else
begin
with newHints do
begin
Add('First record');
Add('Previous record');
Add('Next record');
Add('Last record');
Add('Insert record');
Add('Delete record');
Add('Edit record');
Add('Save record');
Add('Cancel record');
Add('Refresh record');
end;

SetHints(newHints);

msg[wbkFirst] := 'First';

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 64
msg[wbkPrior] := 'Prior';
msg[wbkNext] := 'Next';
msg[wbkLast] := 'Last';
msg[wbkInsert] := 'Insert';
msg[wbkDelete] := 'Delete';
msg[wbkPost] := 'Save';
msg[wbkCancel] := 'Cancel';
msg[wbkRefresh] := 'Refresh';
msg[wbkEdit] := 'Edit';
end;

FCaptions.Clear;
if FCaptionEnabled then
begin
for i:=Ord(Low(FBtnNavigators)) to Ord(High(FBtnNavigators))
do
FCaptions.Add(msg[TWWBtnKind(i)]);
end;
end;

procedure TWWDBNavigator.SetCaptionEnabled(const Value: boolean);


begin
FCaptionEnabled := Value;
if Value = False then
FCaptions.Clear
else
begin
if FCaptions.Count = 0 then
SetIndonesianLanguage(FIndonesianLanguage);
end;
end;

end.

Bagaimana Cara Membuat Event?

Membuat event seperti pada contoh di atas sebenarnya cukup mudah. Jika masih belum
terlalu jelas dengan contoh di atas, mari kita lihat contoh pembuatan event yang lebih
sederhana. Event sebenarnya merupakan pointer ke method / prosedure. Pada contoh unit
classPersegiPanjang, misalkan kita akan membuat event SebelumPanjangBerubah, yang
akan terpicu sebelum panjang persegi panjang diubah. Pertama kita harus membuat tipe
data untuk event yang akan ditrigger, dan parameter yang akan muncul pada event
tersebut. Misal kita hanya akan mengirimkan objek persegi panjang yang dibuat dan
panjangnya. Maka kita membuat signature dari event yang akan kita buat terdiri atas
Sender dengan tipe TObject.
TPersegiPanjangEvent = procedure (Sender:TObject; Panjang:double) of
Object;

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 65
Berikutnya kita perlu variabel private yang tipenya TPersegiPanjangEvent dan
membuat satu property yang namanya akan muncul di Event pada Object Inspector.
published
property SebelumPanjangBerubah:TPersegiPanjangEvent
read FPersegiPanjangEvent write FPersegiPanjangEvent;

Berikutnya kita perlu memanggil event ini, persis sebelum panjang diubah. Dengan
catatan kalau programmer yang menggunakan komponen kita sudah memasukkan kode
dalam event SebelumPanjangBerubah. Jika tidak, tidak usah dipanggil.
procedure TPersegiPanjang.SetPanjang(const Value: double);
begin
if Assigned(FPersegiPanjangEvent) then
FPersegiPanjangEvent(Self, Value);
FPanjang := Value;
end;

Pada saat digunakan pada formTest, contohnya adalah sebagai berikut :


begin
pp := TPersegiPanjang.Create(1, 1);
pp.SebelumPanjangBerubah := Self.TestEvent;
pp.Panjang := 10;
pp.Free;
end;

procedure TformTest.TestEvent(Sender: TObject; Panjang: double);


begin
showMessage('Panjang akan diubah menjadi ' + VarToStr(Panjang));
end;

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 66
7 Referensi
[Budd] Timothy Budd, An Introduction to Object-Oriented Programming, Addison-
Wesley, 1991
[Cornell] Gary Cornell and Cay S. Horstmann, Core Java, SunSoft Press A Prentice Hall
Title, 1996
[Deitel] Harvey M. Deitel, Paul J. Deitel, C++ How to Program, Deitel & Associates, Inc,
1998
[Horstmann], Cay S Horstmann, Mastering Object Oriented Design in C++, John Wiley
& Sons, Inc., 1995
[Stroustrup], Bjarne Stroustrup, What is ‘‘ObjectOriented Programming’’? (1991 revised
version), 1991
[Teixeira], Steve Teixeira, Xavier Pacheco, Borland® Delphi™ 6 Developer’s Guide

Membuat Komponen Sendiri dengan Delphi – Wisnu Widiarta


Halaman 67

You might also like